<template>
    <div>
        <!-- 面包屑 -->
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>商品管理</el-breadcrumb-item>
            <el-breadcrumb-item>参数列表</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 主题内容 -->
        <el-card>
            <!-- alert 警示框 -->
            <el-alert
                title="注意：只允许为第三级分类设置相关参数"
                type="warning"
                :closable="false"
                show-icon>
            </el-alert>
            <el-row class="cat_opt">
                <el-col>
                    <span>请选择商品分类：</span>
                <!-- 级联选择器， options指定数据源  props用来配置对象 -->
                    <el-cascader
                        expand-trigger="hover"
                        :options="cateList"
                        :props="cascaderProps"
                        @change="parentParamsChanged"
                        v-model="selectedCateKey"
                        clearable>
                    </el-cascader>
                    
                </el-col>
                <el-col>
                <el-tabs v-model="activeName" @tab-click="handleTabClick">
                    <!-- 静态属性的面板 -->
                    <el-tab-pane label="动态参数" name="many">
                        <el-button type="primary" size="small" :disabled ="disabled" @click="addDialogVisible = true">添加参数</el-button>
                        <!-- 表格 -->
                        <el-table
                            :data="tableData"
                            border
                            style="width: 100%"
                            stripe>
                            <!-- 展开行 -->
                            <el-table-column 
                                type="expand">
                                <template slot-scope="scope">
                                <el-tag
                                    :key="index"
                                    v-for="(tag,index) in scope.row.attr_vals"
                                    closable
                                    :disable-transitions="false"
                                    @close="handleClose(scope.row, index)">
                                    {{tag}}
                                </el-tag>
                                <el-input
                                    class="input-new-tag"
                                    v-if="scope.row.inputVisible"
                                    v-model="scope.row.inputValue"
                                    ref="saveTagInput"
                                    size="small"
                                    @keyup.enter.native="handleInputConfirm(scope.row)"
                                    @blur="handleInputConfirm(scope.row)"
                                    >
                                </el-input>
                                <el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>
                                </template>
                            </el-table-column>
                            <el-table-column 
                                label="#"
                                type="index">
                                <!-- 索引列 -->
                            </el-table-column>
                            <el-table-column
                                prop="attr_name"
                                label="参数名称"
                                width="180">
                            </el-table-column>
                            <el-table-column
                                label="操作">
                                <template slot-scope="scope" >
                                    <el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.attr_id)">编辑</el-button>
                                    <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeParamsById(scope.row.attr_id)">删除</el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                    </el-tab-pane>
                    <!-- 静态属性的面板 -->
                    <el-tab-pane label="静态属性" name="only">
                        <el-button type="primary" size="small" :disabled ="disabled" @click="addDialogVisible = true">添加参数</el-button>
                        <el-table
                            :data="tableData"
                            border
                            style="width: 100%"
                            stripe>
                            <!-- 展开行 -->
                            <el-table-column 
                                type="expand">
                                <template slot-scope="scope">
                                <el-tag
                                    :key="index"
                                    v-for="(tag,index) in scope.row.attr_vals"
                                    closable
                                    :disable-transitions="false"
                                    @close="handleClose(scope.row, index)">
                                    {{tag}}
                                </el-tag>
                                <el-input
                                    class="input-new-tag"
                                    v-if="scope.row.inputVisible"
                                    v-model="scope.row.inputValue"
                                    ref="saveTagInput"
                                    size="small"
                                    @keyup.enter.native="handleInputConfirm(scope.row)"
                                    @blur="handleInputConfirm(scope.row)"
                                    >
                                </el-input>
                                <el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>
                                </template>
                            </el-table-column>
                            <el-table-column 
                                label="#"
                                type="index">
                                <!-- 索引列 -->
                            </el-table-column>
                            <el-table-column
                                prop="attr_name"
                                label="属性名称"
                                width="180">
                            </el-table-column>
                            <el-table-column
                                label="操作">
                                <template slot-scope="scope">
                                    <el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.attr_id)">编辑</el-button>
                                    <el-button type="danger" icon="el-icon-delete" size="mini" @click="removeParamsById(scope.row.attr_id)">删除</el-button>
                                </template>
                            </el-table-column>
                        </el-table>
                    </el-tab-pane>
                </el-tabs>
                </el-col>
            </el-row>
        </el-card>

        <!-- 添加参数的对话框 让动态和静态都是共用的，就要用到计算属性 -->
        <el-dialog
            :title="'添加'+titleText"
            :visible.sync="addDialogVisible"
            width="50%"
            @close="addDialogClosed">
            <!-- 添加动态参数的表单 -->
            <el-form :model="addParamsForm" :rules="addParamsFormRules" ref="ruleParamsFormRef" label-width="100px" >
                <el-form-item :label="titleText" prop="attr_name">
                    <el-input v-model="addParamsForm.attr_name"></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="addDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="addParams">确 定</el-button>
            </span>
        </el-dialog>

        <!-- 修改参数的对话框 让动态和静态都是共用的，就要用到计算属性 -->
        <el-dialog
            :title="'修改'+titleText"
            :visible.sync="editDialogVisible"
            width="50%"
            @close="editDialogClosed">
            <!-- 添加动态参数的表单 -->
            <el-form :model="editParamsForm" :rules="addParamsFormRules" ref="ruleParamsFormRef" label-width="100px" >
                <el-form-item :label="titleText" prop="attr_name">
                    <el-input v-model="editParamsForm.attr_name"></el-input>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="editDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="editParams">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
    export default {
        name : 'Params',
        data() {
            return {
                cateList : [],  //商品分类列表
                cascaderProps:{   // 给商品分类列表的设置，不设置这些显示不出来
                    value: 'cat_id',
                    label: 'cat_name',
                    children: 'children',
                },
                selectedCateKey:[],  // 级联选择框的双向绑定数组 里面是id
                ParamsId:'', // 保存级联选择器的最后一项id
                activeName: 'many', // tabs标签页默认显示哪个
                tableData: [],  // 动态静态参数的数据（共用）
                addDialogVisible: false, // 显示或隐藏动态添加参数的
                addParamsForm: {   // 动态添加表单的数据(双向绑定)
                    attr_name:'',  // 添加参数的名称
                },
                addParamsFormRules:{    // 添加动态参数的验证规则
                   attr_name:[
                       {
                           required:true,
                           message: '请输入参数名称',
                           trigger: 'blur'
                       }
                   ] 
                },
                // 修改参数属性
                editDialogVisible: false,  // 显示或隐藏修改参数的对话框
                editParamsForm:{
                    attr_name: '', // 修改属性对话框的名称
                },
                // 不能写这下面两个，因为这是共用的，第一行点击添加了，第二的也会添加，要在item循环那里给他们不一样的布尔值
                // inputVisible: false,  // 在展开行中控制按钮与文本框的切换显示
                // inputValue: '' // 展开行中tab的input的的内容
            }
            
        },
        created(){
            this.getCateList()  // 获取所有的商品列表参数
        },
        methods:{
            // 获取所有的商品列表参数
            async getCateList(){
                const {data : res } = await this.$http.get('categories')
                if(res.meta.status != 200) return this.$message.error(res.meta.msg)
                this.cateList = res.data
            },
            // 级联选择器的值发生变化触发的函数
             parentParamsChanged(){
                // console.log(this.selectedCateKey);
                if(this.selectedCateKey.length === 3){
                    this.getParamsList()  // 这个有变化就要该id的获取参数列表
                }else {
                    this.tableData = []
                }
                
            },
            // tabs标签发生变化触发的函数
            handleTabClick() {
                // console.log(this.activeName);
                this.getParamsList()  // tab栏有切换也要重新获取
            },
            // 获取该id的参数列表
            async getParamsList(){
                this.ParamsId = this.selectedCateKey[this.selectedCateKey.length - 1]
                // console.log(ParamsId);
                const {data : res} = await this.$http.get(`categories/${this.ParamsId}/attributes`,{
                    params:{
                        sel:this.activeName // 这里有 many和only 是tab切换决定
                    }
                })
                if(res.meta.status != 200) return this.$message.error(res.meta.msg)
                // 将res.data.attr_vals 变为数组
                res.data.forEach(item => {
                    // .split() 把一个字符串分割成字符串数组，不改变原始字符串。
                    // 如果没有值则返回空字符串（空字符串使用split分割会返回一个 [" "]）
                    item.attr_vals = item.attr_vals? item.attr_vals.split(' ') : []
                    // 在展开行中控制文本框的显示或隐藏(遍历时每一行的都不影响)
                    item.inputVisible = false
                    // 文本框中输入的值(为了保证第一行和第二行的数据不受影响)
                    item.inputValue = ''
                })
                this.tableData = res.data
                // console.log(this.tableData);  //属性的值
                
            },
            // 添加参数对话框的关闭事件
            addDialogClosed(){
                this.$refs.ruleParamsFormRef.resetFields()
            },
            // 添加参数对话框中的确定按钮
            async addParams(){
                // console.log(this.addParamsForm.attr_name); // 用户输入的参数名称
                // console.log(this.ParamsId); // 分类 ID
                // console.log(this.activeName); // [only,many]
                const {data : res} = await this.$http.post(`categories/${this.ParamsId}/attributes`,{
                    attr_name:this.addParamsForm.attr_name,
                    attr_sel:this.activeName
                })
                if(res.meta.status != 201) return this.$message.error(res.meta.msg)
                this.$message.success(res.meta.msg)
                this.getParamsList() // 重新调用参数列表
                this.addDialogVisible = false
            },
            // 修改参数的属性的按钮
            async showEditDialog(attr_id){
                this.editDialogVisible = true
                const {data : res} = await this.$http.get(`categories/${this.ParamsId}/attributes/${attr_id}`,{params:{attr_sel:this.activeName}})
                if(res.meta.status != 200) return this.$message.error(res.meta.msg)
                this.editParamsForm = res.data

            },
            // 修改参数的属性的关闭事件
            editDialogClosed(){
                this.$refs.ruleParamsFormRef.resetFields() // 表单重置
            },
            // 修改参数属性对话框中的确定事件
            editParams(){
                // 先进行表单预验证
                this.$refs.ruleParamsFormRef.validate(async valid => {
                    // console.log(valid); // valid会返回true / false
                    if(!valid) return
                    const {data: res} = await this.$http.put(`categories/${this.ParamsId}/attributes/${this.editParamsForm.attr_id}`,{
                        attr_name:this.editParamsForm.attr_name,
                        attr_sel:this.activeName
                    })
                    if(res.meta.status != 200) return this.$message.error(res.meta.msg)
                    this.$message.success(res.meta.msg)
                    this.getParamsList() // 重新获取参数列表
                    this.editDialogVisible = false
                })
            },
            // 删除属性的按钮事件
            async removeParamsById(attr_id){
                const confirmResult = await this.$confirm('是否将此属性永久删除','提示',{
                    confirmButtonText:'确定',
                    cancelButtonText:'取消',
                    type: 'warning'
                }).catch(err => err)   //捕获异常
                // 确定删除返回 confirm
                // 取消删除返回 cancel
                // console.log(confirmResult)
                if(confirmResult !== 'confirm') return this.$message.info('已取消删除')
                const {data: res} = await this.$http.delete(`categories/${this.ParamsId}/attributes/${attr_id}`)
                if(res.meta.status != 200) return this.$message.error(res.meta.msg)
                this.$message.success(res.meta.msg)
                this.getParamsList()
                this.editDialogVisible = false
            },
            // 展开行中要删除的属性
            handleClose(row,index) {
                // splice 删除会改变原始数组！。
                row.attr_vals.splice(index, 1)
                this.saveAttrVals(row)
            },
            // 在展开行中点击按钮出现文本输入框
            showInput(row) {
                row.inputVisible = true;
                // $nextTick 方法的作用，就是当页面上的元素重新渲染之后，才会执行回调函数中的代码 （要等页面元素渲染出来才有）
                this.$nextTick(_ => { 
                this.$refs.saveTagInput.$refs.input.focus(); //获取文本框的焦点
                });
            },
            // 在展开行中文本框失去焦点或摁下了enter键都会触发的函数
            async handleInputConfirm(row) {
                // 用户输入非法内容
                if(row.inputValue.trim().length === 0){
                    row.inputValue = ''
                    row.inputVisible = false;  // 隐藏文本输入框
                    return
                }
                // 用户输入正确的内容.
                row.attr_vals.push(row.inputValue)
                row.inputVisible = false;
                this.saveAttrVals(row) 
                
            },
            // 在展开行中对 attr_vals 的添加和删除的方法，都是调用同一个api
            async saveAttrVals(row){
                const {data:res} = await this.$http.put(`categories/${this.ParamsId}/attributes/${row.attr_id}`,{
                    attr_name:row.inputValue,//新属性的名字
                    attr_sel:this.activeName,
                    attr_vals:row.attr_vals.join(' ')
                })
                if(res.meta.status != 200) return this.$message.error(res.meta.msg)
                this.$message.success(res.meta.msg)
            }
        },
        computed: {  // 计算属性
            // 控制按钮的禁用与启用
            disabled() {  
                if(this.selectedCateKey.length != 3){
                    return true
                }
                return false
            },
            // 动态计算添加参数的标题文本
            titleText(){
                if(this.activeName === 'many') return '动态参数'
                return '静态参数'
            },
            

        }
    }
</script>

<style scoped>
.cat_opt{
    margin: 15px 0px;
}
.input-new-tag {
    width: 150px;
    margin-left: 10px;
    vertical-align: bottom;
  }
</style>